import { Bus } from "../../Bus";
import { IMixer } from "../IMixer";
import { VRC6Pulse } from "./Pulse";
import { VRC6Sawtooth } from "./Sawtooth";

export enum VRC6Channels {
	Pulse1, Pulse2, Sawtooth
}

const Zoom = [752, 752, 752];

export class VRC6Mixer implements IMixer {

	private pulse1: VRC6Pulse;
	private pulse2: VRC6Pulse;
	private sawtooth: VRC6Sawtooth;

	private lastAmps = [0, 0, 0];
	private bus: Bus;

	constructor(bus: Bus) {
		this.bus = bus;
		this.pulse1 = new VRC6Pulse(this, VRC6Channels.Pulse1);
		this.pulse2 = new VRC6Pulse(this, VRC6Channels.Pulse2);
		this.sawtooth = new VRC6Sawtooth(this);
	}

	UpdateAmp(value: number, channel: VRC6Channels) {
		const delta = this.lastAmps[channel] - value;
		this.lastAmps[channel] = value;
		if (delta === 0)
			return;

		this.bus.apu.blipBuf.BlipAddDelta(this.bus.apu.clock, delta * Zoom[channel]);
	}

	WriteIO(address: number, value: number) {
		switch (address) {
			case 0x9000:
			case 0x9001:
			case 0x9002:
				this.pulse1.WriteIO(address, value);
				break;
			case 0xA000:
			case 0xA001:
			case 0xA002:
				this.pulse2.WriteIO(address, value);
				break;
			case 0xB000:
			case 0xB001:
			case 0xB002:
				this.sawtooth.WriteIO(address, value);
				break;
		}
	}

	ClockRate() {
		this.pulse1.ClockRate();
		this.pulse2.ClockRate();
		if (this.bus.apu.clock & 1)
			this.sawtooth.ClockRate();
	}
}